package org.springframework.social.dao;


import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;

public interface Dao<T, ID extends Serializable> {

    /**
     * Delete.
     * 
     * @param entity the entity
     */
    void delete(T entity);

    /**
     * Find object by criteria.
     * 
     * @param criteria the criteria
     * 
     * @return the list
     */
    List findObjectByCriteria(DetachedCriteria criteria);
    
    /**
     * Find by criteria.
     * 
     * @param criteria the criteria
     * 
     * @return the list< t>
     */
    List<T> findByCriteria(DetachedCriteria criteria);
    
    /**
     * Find by criteria.
     * 
     * @param criteria the criteria
     * @param firstResult the first result
     * @param maxResults the max results
     * 
     * @return the list< t>
     */
    List<T> findByCriteria(DetachedCriteria criteria,  int firstResult, int maxResults);

    /**
     * Find by example.
     * 
     * @param entity the entity
     * 
     * @return the list< t>
     */
    //List<T> findByExample(T entity);

    /**
     * Find by id.
     * 
     * @param id the id
     * 
     * @return the T
     */
    T findById(ID id);

    /**
     * Merge a detached instance.
     * 
     * @param entity to merge
     * 
     * @return the T
     */
    T merge(T entity);

    /**
     * Save.
     * 
     * @param entity the entity
     * 
     * @return the T
     */
    T save(T entity);
    
    /**
     * Load.
     * 
     * @param c the c
     * @param id the id
     * 
     * @return the t
     * 
     * @throws DataAccessException the data access exception
     */
    T load(Class c, Serializable id) throws DataAccessException;
    
    /**
     * Evict.
     * 
     * @param entity the entity
     */
    void evict(T entity);

    /**
     * Update.
     * 
     * @param entity the entity
     * 
     * @return the T
     */
    T update(T entity);   
    
	/**
	 * Bulk update.
	 * 
	 * @param queryString the query string
	 * @param value the value
	 * 
	 * @return the int
	 */
	int bulkUpdate(String queryString, Object value);
	
	/**
	 * Bulk update.
	 * 
	 * @param queryString the query string
	 * @param values the values
	 * 
	 * @return the int
	 */
	int bulkUpdate(String queryString, Object[] values);
	
	int bulkUpdateByNamedParam(String queryString, String[] paramNames, Object[] values);

	/**
	 * Bulk update.
	 * 
	 * @param queryString the query string
	 * 
	 * @return the int
	 */
	int bulkUpdate(String queryString);
	
	/**
	 * Persist.
	 * 
	 * @param entity the entity
	 * 
	 * @throws DataAccessException the data access exception
	 */
	void persist(Object entity) throws DataAccessException;
	
	/**
	 * Find.
	 * 
	 * @param query the query
	 * 
	 * @return the list
	 */
	List find(String query);
	
	List find(String query, int firstResult, int maxResults);
	
	/**
	 * Find by named param.
	 * 
	 * @param queryString the query string
	 * @param values the values
	 * @param paramNames the param names
	 * @param firstResult the first result
	 * @param maxResults the max results
	 * 
	 * @return the list< t>
	 */
    List<T> findByNamedParam (String queryString, String paramNames[], Object values[],
			int firstResult, int maxResults);
    
    /* Find by named param.
	 * 
	 * @param queryString the query string
	 * @param values the values
	 * @param paramNames the param names
	 * 
	 * @return the list< t>
	 */
   /**
     * Find by named param.
     * 
     * @param queryString the query string
     * @param paramNames the param names
     * @param values the values
     * 
     * @return the list< t>
     */
    List<T> findByNamedParam (String queryString, String paramNames[], Object values[]);
    
    /**
     * Find by named param.
     * 
     * @param queryString the query string
     * @param paramName the param name
     * @param value the value
     * 
     * @return the list< t>
     */
    List<T> findByNamedParam(String queryString, String paramName, Object value);
    
      
    /**
     * Find by named param.
     * 
     * @param queryString the query string
     * @param paramName the param name
     * @param value the value
     * @param firstResult the first result
     * @param maxResults the max results
     * 
     * @return the list< t>
     */
    List<T> findByNamedParam(String queryString, String paramName, Object value,
			int firstResult, int maxResults);
    
    /**
     * Find general object by named param.
     * 
     * @param queryString the query string
     * @param paramName the param name
     * @param value the value
     * 
     * @return the list
     */
    List findObjectByNamedParam(String queryString, String paramName, Object value);
    
    /**
     * Find object by named param.
     * 
     * @param queryString the query string
     * @param paramName the param name
     * @param value the value
     * @param firstResult the first result
     * @param maxResults the max results
     * 
     * @return the list
     */
    List findObjectByNamedParam(String queryString, String paramName, Object value,
			final int firstResult, final int maxResults); 
   
    /**
     * Find object by named param.
     * 
     * @param queryString the query string
     * @param paramNames the param names
     * @param values the values
     * 
     * @return the list
     */
    List findObjectByNamedParam(String queryString, String paramNames[], Object values[]);
    
    /**
     * Find object by named param.
     * 
     * @param queryString the query string
     * @param paramNames the param names
     * @param values the values
     * @param firstResult the first result
     * @param maxResults the max results
     * 
     * @return the list
     */
    List findObjectByNamedParam(String queryString, String paramNames[], Object values[],
			final int firstResult, final int maxResults);
    
    void enabledFilter(String filterName, String paramName, Object value);
	
	void enabledFilter(String filterName);
	
	Integer bulkExecuteSql(String queryString);

}
